#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define Bool int
#define true 1
#define false 0
#define MAX 30              //可输入的最大人数
#define MAX_NAME_LENGTH 20       //姓名最大字节数

enum{Excellent = 0,Well = 1,Medium = 2,Pass = 3,NoPass = 4};

int StudentNumber[MAX];     //学号数组
int Score[MAX];             //分数数组
int n;                      //要输入的学生人数
char StudentName[MAX][MAX_NAME_LENGTH] = {};

void FirstPage();           //显示菜单
void Input(int [],int [],int);
void CaculateTotalAndAverage(int[],int);
int Ascend(int a,int b);
int Descend(int a,int b);
void Sort(int[],int,int (*p)(int a,int b));
int BinarySearch(int[],int);        //根据传入的int变量在传入的数组中进行二分查找，如果找到则返回该元素下标，若没有找到则返回-1
void SeachByStudentNumber(int[]);
void Count(int[]);    //统计
void List(int[],int[]);
void SortByName(char [MAX][MAX_NAME_LENGTH]);       //按名字的字典顺序排序
void SearchByName(char [MAX][MAX_NAME_LENGTH],char [MAX_NAME_LENGTH]);

int main()
{
    while(true)
    {
        FirstPage();
    }
    return 0;
}

void FirstPage()
{
    int choice;
    int i;
    printf("1.Input record\n");
    printf("2.Caculate total and average score of course\n");
    printf("3.Sort in descending order by score\n");
    printf("4.Sort in ascending order by score\n");
    printf("5.Sort in ascending order by number\n");
    printf("6.Sort in dictionary order by name\n");
    printf("7.Search by number\n");
    printf("8.Search by name\n");
    printf("9.Statistic analysis\n");
    printf("10.List record\n");
    printf("0.Exit\n");
    printf("\nPlease enter your choice:\n");
    scanf("%d",&choice);
    switch(choice)
    {
    case 1:
        system("cls");
        printf("请输入学生人数:\n");
        scanf("%d",&n);
        Input(StudentNumber,Score,n);
        break;
    case 2:
        system("cls");
        CaculateTotalAndAverage(Score,n);
        break;
    case 3:
        system("cls");
        Sort(Score,n,Descend);
        for(i = 0; i < n; i++)
        {
            printf("学号:%d\t分数:%d\n",StudentNumber[i],Score[i]);
        }
        break;
    case 4:
        system("cls");
        Sort(Score,n,Ascend);
        for(i = 0; i < n; i++)
        {
            printf("学号:%d\t分数:%d\n",StudentNumber[i],Score[i]);
        }
        break;
    case 5:
        system("cls");
        Sort(StudentNumber,n,Ascend);
        for(i = 0;i < n;i++)
        {
            printf("学号:%d\t姓名:%s\t分数:%d\n",StudentNumber[i],StudentName[i],Score[i]);
        }
        break;
    case 6:
        system("cls");
        SortByName(StudentName);
        for(i = 0;i < n;i++)
        {
            printf("学号:%d\t姓名:%s\t分数:%d\n",StudentNumber[i],StudentName[i],Score[i]);
        }
        break;
    case 7:
        system("cls");
        SeachByStudentNumber(StudentNumber);
        break;
    case 8:
        system("cls");
        printf("请输入要查找的名字:\n");
        char NameToSearch[MAX_NAME_LENGTH];
        scanf("%s",NameToSearch);
        SearchByName(StudentName,NameToSearch);
        break;
    case 9:
        system("cls");
        Count(Score);
        break;
    case 10:
        system("cls");
        List(StudentNumber,Score);
        break;
    case 0:
        exit(0);
    default:
        printf("请重新选择:\n");
        break;
    }
}
void Input(int StudentNumber[],int Score[],int n)
{
    int i;
    char temp[MAX_NAME_LENGTH];
    for(i = 0; i < n; i++)
    {
        printf("请输入名字:\n");
        scanf("%s",temp);
        strcpy(StudentName[i],temp);
        printf("请输入学号:\n");
        scanf("%d",&StudentNumber[i]);
        printf("请输入成绩:\n");
        scanf("%d",&Score[i]);
    }
    printf("输入成功\n");
}

void CaculateTotalAndAverage(int Score[],int n)
{
    int sum = 0;
    double average = 0;
    int i;
    for(i = 0; i < n; i++)
    {
        sum += Score[i];
    }
    average = sum / (1.0 * n);
    printf("学生总分为:%d,平均分为:%.2lf\n",sum,average);
}
/*
 *使用选择排序
 */
void Sort(int Score[],int n,int (*p)(int a,int b))
{
    int CurrentIndex;       //当前索引
    int i,j;
    int temp;
    char temp_array[MAX_NAME_LENGTH];
    for(i = 0; i < n; i++)
    {
        CurrentIndex = i;
        for(j = i + 1; j < n; j++)
        {
            if((*p)(Score[j],Score[CurrentIndex]))
            {
                CurrentIndex = j;
            }
        }
        if(i != CurrentIndex)
        {
            temp = Score[i];
            Score[i] = Score[CurrentIndex];
            Score[CurrentIndex] = temp;

            temp = StudentNumber[i];
            StudentNumber[i] = StudentNumber[CurrentIndex];
            StudentNumber[CurrentIndex] = temp;

            strcpy(temp_array,StudentName[i]);
            strcpy(StudentName[i],StudentName[CurrentIndex]);
            strcpy(StudentName[CurrentIndex],temp_array);
        }
    }
}

int Ascend(int a,int b)
{
    return a < b;
}

int Descend(int a,int b)
{
    return a > b;
}

int BinarySearch(int array[],int SearchNumber)
{
    int low = 0,high = n - 1,mid;
    int IndexToReturn = -1;
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(SearchNumber > array[mid])
        {
            low = mid + 1;
        }
        else if(SearchNumber < array[mid])
        {
            high = mid - 1;
        }
        else
        {
            IndexToReturn = mid;
            break;
        }
    }

    return IndexToReturn;

}

void SeachByStudentNumber(int StudentNumber[])
{
    Sort(StudentNumber,n,Ascend);
    int index;
    int SeaechNumber;
    printf("请输入要查找的学号:\n");
    scanf("%d",&SeaechNumber);
    index = BinarySearch(StudentNumber,SeaechNumber);
    if(index == -1)
    {
        printf("未找到该学生!\n");
        return ;
    }
    else
    {
        printf("学号:%d\t成绩:%d\n",StudentNumber[index],Score[index]);
    }
}
void Count(int Score[])
{
    int i;
    int Population[5] = {};
    double Percent[5] = {};
    for(i = 0;i < n;i++)
    {
        if(Score[i] >= 90 && Score[i] <= 100)
        {
            Population[Excellent]++;
        }
        else if(Score[i] >= 80 && Score[i] < 90)
        {
            Population[Well]++;
        }
        else if(Score[i] >= 70 && Score[i] < 80)
        {
            Population[Medium]++;
        }
        else if(Score[i] >= 60 && Score[i] < 70)
        {
            Population[Pass]++;
        }
        else
        {
            Population[NoPass]++;
        }
    }
    Percent[Excellent] = Population[Excellent] / (1.0 * n);
    Percent[Well] = Population[Well] / (1.0 * n);
    Percent[Medium] = Population[Medium] / (1.0 * n);
    Percent[Pass] = Population[Pass] / (1.0 * n);
    Percent[NoPass] = Population[NoPass] / (1.0 * n);
    printf("优秀人数:%d\t优秀的百分比:%.2lf\n",Population[Excellent],Percent[Excellent]);
    printf("良好人数:%d\t良好的百分比:%.2lf\n",Population[Well],Percent[Well]);
    printf("中等人数:%d\t中等的百分比:%.2lf\n",Population[Medium],Percent[Medium]);
    printf("及格人数:%d\t及格的百分比:%.2lf\n",Population[Pass],Percent[Pass]);
    printf("不及格人数:%d\t不及格的百分比:%.2lf\n",Population[NoPass],Percent[NoPass]);
}

void List(int StudentNumber[],int Score[])
{
    int i;
    for(i = 0;i < n;i++)
    {
        printf("学号:%d\t姓名:%s\t成绩:%d\n",StudentNumber[i],StudentName[i],Score[i]);
    }
}

void SortByName(char StudentName[MAX][MAX_NAME_LENGTH])
{
    int i,j;
    int MinNameIndex;           //选择排序用于记录第一层循环的索引的变量
    char temp[MAX_NAME_LENGTH];
    int temp_number;
    for(i = 0;i < n;i++)
    {
        MinNameIndex = i;
        for(j = i + 1;j < n;j++)
        {
            if(strcmp(StudentName[MinNameIndex],StudentName[j]) > 0)
            {
                MinNameIndex = j;
            }
        }
        strcpy(temp,StudentName[i]);
        strcpy(StudentName[i],StudentName[MinNameIndex]);
        strcpy(StudentName[MinNameIndex],temp);

        temp_number = StudentNumber[i];
        StudentNumber[i] = StudentNumber[MinNameIndex];
        StudentNumber[MinNameIndex] = temp_number;

        temp_number = Score[i];
        Score[i] = Score[MinNameIndex];
        Score[MinNameIndex] = temp_number;
    }
}

void SearchByName(char StudentName[MAX][MAX_NAME_LENGTH],char NameToSearch[MAX_NAME_LENGTH])
{
    int i;
    for(i = 0;i < n;i++)
    {
        if(strcmp(NameToSearch,StudentName[i]) == 0)
        {
            printf("找到啦:%s\n",StudentName[i]);
            printf("学号为:%d, 成绩为:%d\n",StudentNumber[i],Score[i]);
            break;
        }
        else
        {
            if(i == n - 1)
            {
                printf("没找到!\n");
            }
        }
    }
}
